package controllers

import (
	"time"

	"beego-api-demo/models"

	"github.com/astaxie/beego"
	"github.com/dgrijalva/jwt-go"
)

type UserController struct {
	BaseController
}

func (c *UserController) Register() {
	form := models.RegisterForm{}
	ctlErr := c.parseRequestBodyAndValidate(&form)
	if ctlErr != nil {
		c.RetError(ctlErr, "ParseRequest:", nil)
		return
	}

	regDate := time.Now()
	user, err := models.NewUser(&form, regDate)
	if err != nil {
		c.RetError(errInputData, "NewUserModel:", err)
		return
	}

	if code, err := user.Insert(); err != nil {
		beego.Error()
		if code == models.ErrDupRows {
			c.RetError(errDupUser, "InsertUserToDbBuDuplicate:", err)
		} else {
			c.RetError(errDatabase, "InsertUserToDb:", err)
		}
		return
	}

	c.RetOk("Succes")
}

func (c *UserController) Token() {
	form := models.TokenForm{}
	ctlErr := c.parseRequestBodyAndValidate(&form)
	if ctlErr != nil {
		c.RetError(ctlErr, "ParseRequest:", nil)
		return
	}

	user := models.User{}
	if code, err := user.FindByID(form.Phone); err != nil {
		if code == models.ErrNotFound {
			c.RetError(errNoUser, "FindUserByIdButNotFound:", err)
		} else {
			c.RetError(errDatabase, "FindUserById:", err)
		}
		return
	}

	if ok, err := user.CheckPassword(form.Password); err != nil {
		c.RetError(errSystem, "CheckUserPass:", err)
		return
	} else if !ok {
		c.RetError(errPass, "CheckUserPass:", err)
		return
	}

	tokenString, err := createToken(user.ID, user.Name)
	if err != nil {
		c.RetError(errCreateToken, "jwt.SignedString:", err)
		return
	}

	user.ClearPassword()

	c.RetOk(&models.LoginInfo{UserInfo: &user, Token: tokenString})
}

func createToken(id string, name string) (tokenString string, err error) {
	claims := make(jwt.MapClaims)
	claims["id"] = id
	claims["name"] = name
	claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// Sign and get the complete encoded token as a string
	tokenString, err = token.SignedString([]byte("secret"))
	if err != nil {
		return "", err
	}
	return
}
